home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-21 | 19.5 KB | 746 lines | [TEXT/R*ch] |
- /*
- AETE_da.cp
- © Bob Boylan 1996
-
- Revision History
- MacHack 1996 initial creation
- */
- #include "debug.h"
-
- #include "AETE_da.h"
- #include "AEBuild.h"
- #include "AppAEObj_pd.h"
- #include "ComputerAETE_da.h"
- #include "Helpers_ut.h"
-
- #include <sstream>
- #include <ASRegistry.h>
- #include <UMemoryMgr.h>
- #include <algo.h>
-
-
-
-
- // -----------------------------------------------------------------
- // GetAstring ... handy for getting data out of the AETE
- //
- string
- GetAstring( istream &ioStream, Boolean inDoAlign );
- string
- GetAstring( istream &ioStream, Boolean inDoAlign = true )
- {
- UInt_8 theLen;
- char theString[256];
-
- ioStream.read( &theLen,1 );
- dassert( theLen >= 0 );
- if( theLen > 0 )
- {
- ioStream.read( (unsigned char *)&theString, theLen );
- if( (inDoAlign == true ) &&
- ((theLen & 0x1) == 0 ) )
- {
- UInt_8 theAlignByte;
- ioStream.read( &theAlignByte,1 );
- }
- }
- else
- { // zero len, but we need to align and the len takes one byte
- if( inDoAlign == true )
- {
- UInt_8 theAlignByte;
- ioStream.read( &theAlignByte,1 );
- }
- }
- return string( theString, Int_32(theLen) );
- }
-
- // ------------------------------------------------------------
- // istream getter of comparison ops
- //
- istream& operator >> (istream &ioStream, ComparisonOp_da& outComparison)
- {
- string theName = GetAstring( ioStream );
- Int_32 theOPID;
- ioStream.read( (unsigned char *)&theOPID, 4 );
- string theDesc = GetAstring( ioStream );
-
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of properties
- //
- istream& operator >> (istream &ioStream, Prop_da& outProp)
- {
- outProp._Name = GetAstring( ioStream );
- ioStream.read( (unsigned char *)&outProp._ID, 4 );
- ioStream.read( (unsigned char *)&outProp._Class, 4 );
-
- string theDesc = GetAstring( ioStream );
- Int_16 theFlags;
- ioStream.read( (unsigned char *)&theFlags, 2 );
-
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of elements (aka submodels)
- //
- istream& operator >> (istream &ioStream, Elem_da& outElem)
- {
- ioStream.read( (unsigned char *)&outElem._ID, 4 );
- {
- Int_16 theFormCount;
- ioStream.read( (unsigned char *)&theFormCount, 2 );
- for( Int_16 theFormIndex = 1 ; theFormIndex <= theFormCount ; theFormIndex++ )
- {
- DescType theForm;
- ioStream.read( (unsigned char *)&theForm, 4 );
- }
- }
-
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of enum values
- //
- istream& operator >> (istream &ioStream, EnumValue_da& outEnumValue)
- {
- outEnumValue._Name = GetAstring( ioStream );
- ioStream.read( (unsigned char *)&outEnumValue._ID, 4 );
-
- string theDesc = GetAstring( ioStream );
-
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of enums
- //
- istream& operator >> (istream &ioStream, Enum_da& outEnum)
- {
- ioStream.read( (unsigned char *)&outEnum._ID, 4 );
- {
- Int_16 theValueCount;
- ioStream.read( (unsigned char *)&theValueCount, 2 );
- for( Int_16 theValueIndex = 1 ; theValueIndex <= theValueCount ; theValueIndex++ )
- {
- EnumValue_da theValue;
- ioStream >> theValue;
- outEnum._Values.push_back( theValue );
- }
- }
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of classes
- //
- istream& operator >> (istream &ioStream, Class_da& outClass)
- {
- outClass._Name = GetAstring( ioStream );
- ioStream.read( (unsigned char *)&outClass._ID, 4 );
-
- string theDesc = GetAstring( ioStream );
-
- { // the properties
- Int_16 thePropCount;
- ioStream.read( (unsigned char *)&thePropCount, 2 );
- for( Int_16 thePropIndex = 1 ; thePropIndex <= thePropCount ; thePropIndex++ )
- {
- Prop_da theProp;
- ioStream >> theProp;
- outClass._Props.push_back( theProp );
- }
- }
-
- { // the elements (sub models)
- Int_16 theEleCount;
- ioStream.read( (unsigned char *)&theEleCount, 2 );
- for( Int_16 theEleIndex = 1 ; theEleIndex <= theEleCount ; theEleIndex++ )
- {
- Elem_da theElem;
- ioStream >> theElem;
- outClass._Elems.push_back( theElem );
- }
- }
-
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of event parameters
- //
- istream& operator >> (istream &ioStream, EventParam_da& outEventParam)
- {
- outEventParam._Name = GetAstring( ioStream );
-
- DescType theKeyWord;
- ioStream.read( (unsigned char *)&theKeyWord, 4 );
- DescType theType;
- ioStream.read( (unsigned char *)&theType, 4 );
-
- string theParamDesc = GetAstring( ioStream );
-
- Int_16 theParamFlags;
- ioStream.read( (unsigned char *)&theParamFlags, 2 );
-
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of events
- //
- istream& operator >> (istream &ioStream, Event_da& outEvent)
- {
- outEvent._Name = GetAstring( ioStream, false );
- string theEventDesc = GetAstring( ioStream, false );
- if( ((outEvent._Name.length() + theEventDesc.length() ) & 1 ) == 1 )
- {
- UInt_8 theAlignByte;
- ioStream.read( &theAlignByte,1 );
- }
-
- DescType theEventClass;
- ioStream.read( (unsigned char *)&theEventClass, 4 );
- DescType theEventID;
- ioStream.read( (unsigned char *)&theEventID, 4 );
- DescType theReplyParam;
- ioStream.read( (unsigned char *)&theReplyParam, 4 );
-
- string theReplyDesc = GetAstring( ioStream );
-
- Int_16 theReplyFlags;
- ioStream.read( (unsigned char *)&theReplyFlags, 2 );
-
- DescType theParamType;
- ioStream.read( (unsigned char *)&theParamType, 4 );
-
- string theParamDesc = GetAstring( ioStream );
-
- Int_16 thePFlags;
- ioStream.read( (unsigned char *)&thePFlags, 2 );
-
- {
- Int_16 theAdditionalParamCount;
- ioStream.read( (unsigned char *)&theAdditionalParamCount, 2 );
- for( Int_16 theEParamIndex = 1 ; theEParamIndex <= theAdditionalParamCount ; theEParamIndex++ )
- {
- EventParam_da theEventParam;
- ioStream >> theEventParam;
- outEvent._Params.push_back( theEventParam );
- }
- }
- return ioStream;
- }
- // ------------------------------------------------------------
- // istream getter of suites
- //
- istream& operator >> (istream &ioStream, Suite_da& outSuite)
- {
- outSuite._Name = GetAstring( ioStream, false );
- string theSuiteDescription = GetAstring( ioStream, false );
- if( ((outSuite._Name.length() + theSuiteDescription.length() ) & 1 ) == 1 )
- {
- UInt_8 theAlignByte;
- ioStream.read( &theAlignByte,1 );
- }
- {
- Int_32 theSuiteID;
- ioStream.read( (unsigned char *)&theSuiteID, 4 );
- Int_16 theSuiteLevel;
- ioStream.read( (unsigned char *)&theSuiteLevel, 2 );
- Int_16 theSuiteVersion;
- ioStream.read( (unsigned char *)&theSuiteVersion, 2 );
-
- { // events
- Int_16 theEventCount;
- ioStream.read( (unsigned char *)&theEventCount, 2 );
- for( Int_16 theEventIndex = 1 ; theEventIndex <= theEventCount ; theEventIndex++ )
- {
- Event_da theEvent;
- ioStream >> theEvent;
- outSuite._Events.push_back( theEvent );
- }
- }
-
- { // classes
- Int_16 theClassCount;
- ioStream.read( (unsigned char *)&theClassCount, 2 );
- for( Int_16 theClassIndex = 1 ; theClassIndex <= theClassCount ; theClassIndex++ )
- {
- Class_da theClass;
- ioStream >> theClass;
- outSuite._Classes.push_back( theClass );
- }
- }
-
-
- { // comparison operators
- Int_16 theComparisonCount;
- ioStream.read( (unsigned char *)&theComparisonCount, 2 );
- for( Int_16 theCompIndex = 1 ; theCompIndex <= theComparisonCount ; theCompIndex++ )
- {
- ComparisonOp_da theComp;
- ioStream >> theComp;
- outSuite._CompOps.push_back( theComp);
- }
- }
-
- { // enumerations
- Int_16 theEnumCount;
- ioStream.read( (unsigned char *)&theEnumCount, 2 );
- for( Int_16 theEnumIndex = 1 ; theEnumIndex <= theEnumCount ; theEnumIndex++ )
- {
- Enum_da theEnum;
- ioStream >> theEnum;
- outSuite._Enums.push_back( theEnum );
- }
- }
-
-
- }
- return ioStream;
- }
-
-
- // -----------------------------------------------------------------
- // AnyEnum_2_typeChar_Ptr - ae coercion handler from any enum to char
- // ... will find the char string associated with an enum
- //
- pascal
- OSErr
- AnyEnum_2_typeChar_Ptr( DescType inTypeCode, const void * indataPtr, Size indataSize, DescType intoType, Int_32 inhandlerRefcon, AEDesc *outresult );
- pascal
- OSErr
- AnyEnum_2_typeChar_Ptr( DescType inTypeCode, const void * indataPtr, Size indataSize, DescType intoType, Int_32 inhandlerRefcon, AEDesc *outresult )
- {
-
- Int_32 theEnumValue = (*((Int_32 *) indataPtr));
-
- AETE_da * theAETEP = (AETE_da *) inhandlerRefcon; // refcon holds the aete object *
- dassert( theAETEP != nil );
-
- string theEnumName = theAETEP->GetEnumName( theEnumValue );
-
- OSErr theRetVal = ::AECreateDesc(intoType, (Ptr) theEnumName.c_str(), theEnumName.length(), outresult );
-
- return theRetVal;
- }
- // -----------------------------------------------------------------
- // Boolean_2_typeChar_Ptr - ae coercion handler from boolean to char
- //
- pascal
- OSErr
- Boolean_2_typeChar_Ptr( DescType inTypeCode, const void * indataPtr, Size indataSize, DescType intoType, Int_32 inhandlerRefcon, AEDesc *outresult );
- pascal
- OSErr
- Boolean_2_typeChar_Ptr( DescType inTypeCode, const void * indataPtr, Size indataSize, DescType intoType, Int_32 inhandlerRefcon, AEDesc *outresult )
- {
- #pragma unused( inhandlerRefcon )
-
- Boolean theValue = (*((Boolean *) indataPtr));
- string theValueAsString;
- if( theValue )
- {
- theValueAsString = string("True");
- }
- else
- {
- theValueAsString = string("False");
- }
- OSErr theRetVal = ::AECreateDesc(intoType, (Ptr) theValueAsString.c_str(), theValueAsString.length(), outresult );
-
- return theRetVal;
- }
-
-
- // ---------------------------------------------------------------------------------- AETE
-
- // -----------------------------------------------------------------
- // ctor
- //
- AETE_da::AETE_da()
- : _EnumHandlerUPP( nil ),
- _BooleanHandlerUPP( nil )
-
- {}
- // -----------------------------------------------------------------
- // ctor (with application object)
- //
- AETE_da::AETE_da( AppAEObj_pd *inApp )
- : _EnumHandlerUPP( nil ),
- _BooleanHandlerUPP( nil )
- {
- Clone_ut<StAEDescriptor> theAETE = RetrieveFromApp( inApp );
- if( (*theAETE).mDesc.descriptorType == typeNull )
- {
- // not really scriptable
- }
- else
- { // ok, we now have the data, need to make sense of it ...
- // we can get either a list or a single aete
- if( (*theAETE).mDesc.descriptorType == typeAEList )
- {
- Int_32 theNItems;
- // a list of aetes
- ::AECountItems( &(*theAETE).mDesc, &theNItems );
- for( Int_32 theIndex=1; theIndex<=theNItems; theIndex++ )
- {
- {
- StAEDescriptor theAETEItem;
- DescType theType;
- OSErr anErr = AEGetNthDesc( &(*theAETE).mDesc, theIndex,
- typeWildCard, &theType, &theAETEItem.mDesc );
- StHandleLocker theLock( theAETEItem.mDesc.dataHandle );
- IncorpAETE( theAETEItem.mDesc.dataHandle );
-
- }
-
- }
- }
- else
- {
- StHandleLocker theLock( (*theAETE).mDesc.dataHandle );
- IncorpAETE( (*theAETE).mDesc.dataHandle );
- }
-
-
-
- { // install the coercion handler
- _EnumHandlerUPP = NewAECoercePtrProc( AnyEnum_2_typeChar_Ptr );
- _BooleanHandlerUPP = NewAECoercePtrProc( Boolean_2_typeChar_Ptr );
- // install it
- #if GENERATINGPOWERPC
- OSErr theErr = AEInstallCoercionHandler( typeEnumerated, typeChar, _EnumHandlerUPP, (Int_32)this, false, false );
- theErr = AEInstallCoercionHandler( typeBoolean, typeChar, _BooleanHandlerUPP, (Int_32)this, false, false );
- #else
- OSErr theErr = AEInstallCoercionHandler( typeEnumerated, typeChar, (ProcPtr)_EnumHandlerUPP, (Int_32)this, false, false );
- theErr = AEInstallCoercionHandler( typeBoolean, typeChar, (ProcPtr)_BooleanHandlerUPP, (Int_32)this, false, false );
- #endif
-
- }
-
- }
-
- // for optimization we have this 'last class' bookmark
- ClassIterator_ut theNullSet;
- _LastClass = theNullSet;
-
- }
- // -----------------------------------------------------------------
- // dtor
- //
- AETE_da::~AETE_da()
- {
- // clean up the ae coercion handlers
- if( _EnumHandlerUPP != nil )
- {
-
- #if GENERATINGPOWERPC
- AERemoveCoercionHandler( typeEnumerated, typeChar, _EnumHandlerUPP, false );
- AERemoveCoercionHandler( typeBoolean, typeChar, _BooleanHandlerUPP, false );
- #else
- AERemoveCoercionHandler( typeEnumerated, typeChar, (ProcPtr)_EnumHandlerUPP, false );
- AERemoveCoercionHandler( typeBoolean, typeChar, (ProcPtr)_BooleanHandlerUPP, false );
- #endif
- DisposeRoutineDescriptor( _EnumHandlerUPP );
- DisposeRoutineDescriptor( _BooleanHandlerUPP );
- _EnumHandlerUPP = nil;
- _BooleanHandlerUPP = nil;
- }
- }
-
- // -----------------------------------------------------------------
- // GetProperties ... associated with a given class
- //
- vector<Prop_da>
- AETE_da::GetProperties( const DescType inClassID )
- {
- vector<Prop_da> theRetVal;
- // quick exit check
- if( (*_LastClass)._ID == inClassID )
- {
- theRetVal = (*_LastClass)._Props;
- }
- else
- { // search the list we have already parsed
- ClassIterator_ut theFirstClass( &_Suites );
- ClassIterator_ut theLastClass ( &_Suites,true );
- Class_da theClassWeWant;
- theClassWeWant._ID = inClassID;
- ClassIterator_ut theFoundItem = find( theFirstClass, theLastClass, theClassWeWant );
-
- if( theFoundItem != theLastClass )
- {
- _LastClass = theFoundItem;
- theRetVal = (*_LastClass)._Props;
- }
- }
- return theRetVal;
-
- }
-
- // -----------------------------------------------------------------
- // GetElements ... associated with a given class
- //
- vector<Elem_da>
- AETE_da::GetElements( const DescType inClassID )
- {
- vector<Elem_da> theRetVal;
-
- // quick exit check
- if( (*_LastClass)._ID == inClassID )
- {
- theRetVal = (*_LastClass)._Elems;
- }
- else
- {
- ClassIterator_ut theFirstClass( &_Suites );
- ClassIterator_ut theLastClass ( &_Suites,true );
- if( inClassID != cFinderProcess)
- { // with an object we look in it's element list
- Class_da theClassWeWant;
- theClassWeWant._ID = inClassID;
- ClassIterator_ut theFoundItem = find( theFirstClass, theLastClass, theClassWeWant );
-
- if( theFoundItem != theLastClass )
- {
- _LastClass = theFoundItem;
- theRetVal = (*_LastClass)._Elems;
- }
- }
- else
- { // with an 'application' we hand back all the class types
- while( theFirstClass != theLastClass )
- {
- Elem_da theElem;
- theElem._ID = (*theFirstClass)._ID;
- theRetVal.push_back( theElem );
- ++theFirstClass;
- }
- }
- }
- return theRetVal;
- }
- // -----------------------------------------------------------------
- // GetEnumName ... search all enums for a given value
- //
- string
- AETE_da::GetEnumName( const DescType inEnumValue )
- {
- string theRetVal;
-
- EnumValue_da theValueWeWant;
- theValueWeWant._ID = inEnumValue;
-
- pair< vector<EnumValue_da>::iterator,vector<EnumValue_da>::iterator> theFoundItem
- = equal_range( _EnumMap.begin(), _EnumMap.end(), theValueWeWant );
-
- if( theFoundItem.first != _EnumMap.end() )
- {
- theRetVal = (*(theFoundItem.first))._Name;
- }
- else
- {
- theRetVal = As4CharString( inEnumValue );
- }
-
- return theRetVal;
- }
-
- // -----------------------------------------------------------------
- // GetClassName
- //
- string
- AETE_da::GetClassName( const DescType inClassID )
- {
- string theRetVal;
-
- ClassIterator_ut theFirstClass( &_Suites );
- ClassIterator_ut theLastClass ( &_Suites,true );
- Class_da theClassWeWant;
- theClassWeWant._ID = inClassID;
- ClassIterator_ut theFoundItem = find( theFirstClass, theLastClass, theClassWeWant );
-
-
- if( theFoundItem != theLastClass )
- {
- theRetVal = (*theFoundItem)._Name;
- }
- else
- { // hmmm ... the class wasn't there? must be an application
- if( inClassID == cFinderProcess )
- {
- theRetVal = string("App");
- }
- else
- { // if not, maybe the user can make some sense of it
- theRetVal = As4CharString( inClassID );
- }
- }
- return theRetVal;
- }
-
- // -----------------------------------------------------------------
- // RetrieveFromApp ... get the 'aete' data from the application
- //
- Clone_ut<StAEDescriptor>
- AETE_da::RetrieveFromApp( AppAEObj_pd *inApp )
- {
- ostringstream theStream( ios::in | ios::out );
- theStream << "'----': 0"; // the lang code
- OSErr theErr;
- StAEDescriptor theAppleEvent;
-
- // use gizmos to create the apple event
- theErr = AEBuildAppleEvent( kASAppleScriptSuite, kGetAETE,
- inApp->GetAppAddrType(),
- inApp->GetAppAddr(),
- inApp->GetSizeofAppAddr(),
- kAutoGenerateReturnID, kAnyTransactionID,
- &theAppleEvent.mDesc, theStream.str().c_str() );
- dassert( theErr == noErr );
-
- StAEDescriptor theReplyAppleEvent;
- // and off with it
- theErr = AESend( &theAppleEvent.mDesc, &theReplyAppleEvent.mDesc, kAEWaitReply,
- kAENormalPriority, 61, nil, nil ); // timeout = 61
-
- // package up the return value
- StAEDescriptor *theResult = new StAEDescriptor;
- Clone_ut<StAEDescriptor> theRetVal( theResult );
- if( theErr == noErr )
- {
- theErr = AEGetParamDesc( theReplyAppleEvent, keyDirectObject, typeWildCard, &theResult->mDesc );
- }
-
- return theRetVal;
-
- }
-
-
- // -----------------------------------------------------------------
- // IncorpAETE ... merge with existing data
- //
- void
- AETE_da::IncorpAETE( Handle inAETEHandle )
- {
- StHandleLocker theLock( inAETEHandle );
-
- istringstream theStream( string((char *) *inAETEHandle, GetHandleSize(inAETEHandle) ), ios::in | ios::binary);
- {
- // read the up front stuff
- char theDummy[2];
- theStream.read( theDummy, 2 ); // aete version
-
- theStream.read( theDummy, 2 ) ; // lang
- theStream.read( theDummy, 2 ) ; // script
-
-
- Int_16 theSuiteCount;
- theStream.read( (char *) &theSuiteCount, 2 );
-
- for( Int_16 theIndex = 1 ; theIndex <= theSuiteCount ; theIndex ++ )
- {
- Suite_da theNewSuite;
- theStream >> theNewSuite;
- _Suites.push_back( theNewSuite );
-
-
- { // update the enum map ... needed for quick access to the enum names
- vector<Enum_da>::iterator theEIter = theNewSuite._Enums.begin();
- while( theEIter != theNewSuite._Enums.end() )
- {
- vector<EnumValue_da>::iterator theEVIter = (*theEIter)._Values.begin();
- while( theEVIter != (*theEIter)._Values.end() )
- {
- _EnumMap.push_back( *theEVIter );
- ++theEVIter;
- }
- ++theEIter;
- }
- }
- }
- sort( _EnumMap.begin(), _EnumMap.end() ); // for later binary search
- }
-
- }
-
- // ---------------------------------------------------------------------------------------------
-
- // -----------------------------------------------------------------
- // ClassIterator_ut ctor
- //
- AETE_da::ClassIterator_ut::ClassIterator_ut( vector<Suite_da> * inSuites, Boolean inPointToEnd )
- : _SuitesP( inSuites ),
- _SuiteIndex( 0 ),
- _ClassIndex( 0 )
- {
- dassert( inSuites != nil );
- if( inPointToEnd == true )
- {
- _SuiteIndex = _SuitesP->size();
- }
- else
- { // could be the first suite doesn't have any classes
- while( (_SuiteIndex < _SuitesP->size() ) &&
- ((*_SuitesP)[_SuiteIndex]._Classes.size() == 0 ))
- {
- ++_SuiteIndex;
- }
-
- }
- }
- // -----------------------------------------------------------------
- // != operator
- //
- Boolean
- AETE_da::ClassIterator_ut::operator !=( const ClassIterator_ut & inOther )
- {
- if( (_SuiteIndex == inOther._SuiteIndex) &&
- (_ClassIndex == inOther._ClassIndex) )
- return false;
- else
- return true;
- }
- // -----------------------------------------------------------------
- // ++ operator
- //
- AETE_da::ClassIterator_ut
- AETE_da::ClassIterator_ut::operator ++()
- {
- dassert( _SuiteIndex < _SuitesP->size() );
- dassert( _ClassIndex <= (*_SuitesP)[_SuiteIndex]._Classes.size() );
- if( (_ClassIndex + 1) < (*_SuitesP)[_SuiteIndex]._Classes.size() )
- {
- ++_ClassIndex;
- }
- else
- {
- // see if this suite has any classes, if not then move on to the next one
- ++_SuiteIndex;
- while( (_SuiteIndex < _SuitesP->size() ) &&
- ((*_SuitesP)[_SuiteIndex]._Classes.size() == 0 ))
- {
- ++_SuiteIndex;
- }
- _ClassIndex = 0;
- }
- return *this;
- }
-
-
- // -----------------------------------------------------------------
- // * operator
- //
- Class_da &
- AETE_da::ClassIterator_ut::operator *()
- {
- if( _SuitesP == nil )
- {
- Class_da theRetVal;
- theRetVal._ID = typeNull;
- return theRetVal;
- }
- else
- {
- return (*_SuitesP)[_SuiteIndex]._Classes[_ClassIndex];
- }
- }
-